<!-- DictSelector.vue -->
<template>
  <el-select 
    filterable
    :v-model="modelValue"
    v-bind="getBindValue"
    @change="handleChange"
    :placeholder="placeholder"
    :clearable="clearable"
    remote
    :remote-method="debouncedQuery"
    :loading="loading"
  >
    <el-option
      v-for="item in selectOptions"
      :key="item[valueField]"
      :label="getLabel(item)"
      :value="item[valueField]"
    />
  </el-select>
</template>

<script setup lang="ts">
import { useAttrs, computed, ref } from 'vue'
import { propTypes } from '@/utils/propTypes'
import { debounce } from 'lodash-es'

defineOptions({ name: 'SearchSelector' })

const props = defineProps({
  modelValue: propTypes.any.def(''),
  placeholder: propTypes.string.def('请选择'),
  clearable: propTypes.bool.def(false),
  queryPromise: propTypes.func.isRequired, // 查询Promise函数
  valueField: propTypes.string.def('value'), // 值字段名
  queryField: propTypes.string.def(''), // 标签字段名
  labelField: propTypes.string.def('label'), // 标签字段名
  debounceTime: propTypes.number.def(300) // 防抖时间(ms)
})

const getBindValue = computed(() => {
  const attrs = useAttrs()
  // 使用解构 omit 排除不需要传递的属性
  const { queryPromise, valueField, labelField, debounceTime, ...rest } = props
  return { ...attrs, ...rest }
})
// 定义事件
const emit = defineEmits<{
  (e: 'update:modelValue', value: any): void
  (e: 'change', value: any): void
}>()

// 选项数据
const selectOptions = ref<any[]>([])
const loading = ref(false)

// 防抖查询函数
const debouncedQuery = debounce(async (query: string) => {
  if (!props.queryPromise) return
  
  loading.value = true
  try {
    if(selectOptions.value.length>0 && query==='') return
    const queryData = {}
    if (props.queryField) {
      queryData[props.queryField] = query
    } else {
      queryData[props.labelField] = query
    }
    
    const result = await props.queryPromise(queryData)
    selectOptions.value = Array.isArray(result) ? result : []
  } catch (error) {
    console.error('查询失败:', error)
    selectOptions.value = []
  } finally {
    loading.value = false
  }
}, props.debounceTime)

// 初始化加载
watch(
  () => props.queryPromise,
  async () => {
    await debouncedQuery('')
  },
  {
    immediate: true
  }
)

// 处理 change 事件
const handleChange = (value: any) => {
  emit('update:modelValue', value)
  emit('change', value)
}

// 获取显示标签的函数
const getLabel = (item: any) => {
  // 如果labelField包含+号，则分割并连接
  if (props.labelField.includes('+')) {
    const fields = props.labelField.split('+')
    return fields.map(field => item[field.trim()] || '').filter(Boolean).join('-')
  }
  return item[props.labelField]
}

// 允许父组件访问子组件属性
defineExpose({
  selectOptions: selectOptions,
  refresh: debouncedQuery // 提供刷新方法
})
</script>